package com.wrench.elevator.base.user.service;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.wrench.elevator.base.user.dao.ConsumeDao;
import com.wrench.elevator.base.user.domain.Consume;
import com.wrench.elevator.constant.Result;
import com.wrench.elevator.exception.WrenchException;
import com.wrench.elevator.util.WrenchUtil;

/**
 * @Description: ConsumeService
 * @author yangchenfeng
 * @date Oct 24, 2017 8:02:38 AM
 * @version V1.0
 */
@Component
public class ConsumeService
{
    @Resource
    private ConsumeDao dao;
    
    @Resource
    private FlowService flowService;
    
    @Resource
    private WalletService walletService;
    
    private static final Logger logger = LoggerFactory.getLogger(ConsumeService.class);
    
    /**
     * 消费
     * */
    @Transactional(rollbackFor = WrenchException.class)
    public int addConsume(String user_id, String consume_money, String consume_type)
        throws WrenchException
    {
        // 判空
        if (WrenchUtil.hasNull(user_id, consume_money, consume_type))
        {
            logger.error("==> param is not found , user_id = {} , consume_money = {} , consume_type = {} ",
            
            user_id, consume_money, consume_type);
            throw new WrenchException(Result.PARAM_NOT_FOUND_CODE, Result.PARAM_NOT_FOUND_MESSAGE);
            
        }
        user_id = user_id.trim();
        consume_money = consume_money.trim();
        consume_type = consume_type.trim();
        
        // 判断是否金额数字
        if (!WrenchUtil.isMoneyStr(consume_money))
        {
            logger.error("==> string is not money , consume_money = {} ", consume_money);
            throw new WrenchException(Result.STRING_IS_NOT_MONEY_CODE, Result.STRING_IS_NOT_MONEY_MESSAGE);
        }
        
        // 判断是否整数
        if (!WrenchUtil.isInt(user_id))
        {
            logger.error("==> string is not int type , user_id = {} ", user_id);
            throw new WrenchException(Result.STRING_IS_NOT_INT_CODE, Result.STRING_IS_NOT_INT_MESSAGE);
        }
        
        // 判断是否是正常的消费类型
        if (!WrenchUtil.isVaildConsumeType(consume_type))
        {
            logger.error("==> consume type is not vaild , consume_type = {} ", consume_type);
            throw new WrenchException(Result.CONSUME_TYPE_IS_NOT_VAILD_CODE, Result.CONSUME_TYPE_IS_NOT_VAILD_MESSAGE);
        }
        
        String consume_flow_no = WrenchUtil.getFlowNo(consume_type);
        String consume_time = WrenchUtil.nowTime();
        
        // 扣费
        walletService.consume(consume_money, user_id);
        
        // 流水记录
        flowService.addFlow(consume_type, consume_money, user_id, consume_flow_no, consume_time);
        
        Consume consume = new Consume();
        consume.setConsume_money(Double.valueOf(consume_money));
        consume.setConsume_type(consume_type);
        consume.setUser_id(Integer.valueOf(user_id));
        consume.setConsume_flow_no(consume_flow_no);
        consume.setConsume_time(consume_time);
        
        int commit = -1;
        try
        {
            commit = dao.addConsume(consume);
        }
        catch (Exception e)
        {
            // TODO Auto-generated catch block
            logger.error("==> commit=dao.addConsume(consume) execute error , consume  = {} , error = {}; ", consume, e);
            throw new WrenchException(Result.DB_INSERT_ERROR_CODE, Result.DB_INSERT_ERROR_MESSAGE);
        }
        
        if (commit <= 0)
        {
            logger.error("==> commit=dao.addConsume(consume) execute success , but commit <=0 , commit = {} , consume = {} ",
                commit,
                consume);
            throw new WrenchException(Result.CONSUME_ADD_CONSUME_FAIL_CODE, Result.CONSUME_ADD_CONSUME_FAIL_MESSAGE);
        }
        
        logger.debug("==> commit=dao.addConsume(consume) execute success , commit = {} , consume = {} ",
            commit,
            consume);
        
        return commit;
    }
}
